home *** CD-ROM | disk | FTP | other *** search
- SUBROUTINE EVAL (TOKE, NTOKE, FACTS, TOP, NT, BOT, NB, FAC )
- C*
- C* *******************************
- C* *******************************
- C* ** **
- C* ** EVAL **
- C* ** **
- C* *******************************
- C* *******************************
- C*
- C* SUBPROGRAM :
- C* EVALUATE
- C*
- C* AUTHOR :
- C* ART RAGOSTA
- C* MS 207-5
- C* AMES RESEARCH CENTER
- C* MOFFETT FIELD, CALIF 94035
- C* (415) 694-5578
- C*
- C* PURPOSE :
- C* TO EVALUATE THE REVERSE POLISH STRING, RESULTING IN A
- C* FINAL SCALE FACTOR AND THE PROPER UNITS.
- C*
- C* METHODOLOGY :
- C* NA
- C*
- C* INPUT ARGUMENTS :
- C* TOKE - THE LIST OF TOKENS IN REVERSE POLISH
- C* NTOKE - THE NUMBER OF TOKENS IN 'TOKE'
- C* FACTS - THE SCALE FACTORS FOR EACH ENTRY IN 'TOKE'
- C*
- C* OUTPUT ARGUMENTS :
- C* TOP - THE LIST OF UNITS WHICH ARE IN THE NUMERATOR
- C* NT - THE NUMBER OF ENTRIES IN 'TOP'
- C* BOT - THE LIST OF UNITS WHICH ARE IN THE DENOMINATOR
- C* NB - THE NUMBER OF ENTRIES IN 'BOT'
- C* FAC - THE TOTAL SCALE FACTOR
- C*
- C* INTERNAL WORK AREAS :
- C* TFAC, BFAC - STACKS FOR SCALE FACTORS
- C* TSTACK, BSTACK - STACKS FOR UNIT STRINGS
- C*
- C* COMMON BLOCKS :
- C* NONE
- C*
- C* FILE REFERENCES :
- C* NONE
- C*
- C* SUBPROGRAM REFERENCES :
- C* LENGTH, RIGHT
- C*
- C* ERROR PROCESSING :
- C* NONE
- C*
- C* TRANSPORTABILITY LIMITATIONS :
- C* NONE
- C*
- C* ASSUMPTIONS AND RESTRICTIONS :
- C* NONE
- C*
- C* LANGUAGE AND COMPILER :
- C* ANSI FORTRAN 77
- C*
- C* VERSION AND DATE :
- C* VERSION I.0 7-FEB-85
- C*
- C* CHANGE HISTORY :
- C* 7-FEB-85 INITIAL VERSION
- C*
- C***********************************************************************
- C*
- CHARACTER *600 BSTACK(50), TSTACK(50), T, T1, B, B1
- CHARACTER *6 TOKE(1), TOP(1), BOT(1), TT
- DOUBLE PRECISION FACTS(1), FAC, FSTACK(50)
- C
- FAC = 1.0D0
- NT = 0
- NB = 0
- IF ( NTOKE .LE. 0 ) RETURN
- ISP = 0
- C
- C --- FIRST PASS, CALCULATE SCALE FACTOR
- C
- DO 100 I = 1, NTOKE
- C
- C ----- FOR EXPONENTIATION, GET EXPONENT FROM TOKENS
- C
- IF ( TOKE(I) .EQ. '^') THEN
- TT = TOKE(I-1)
- CALL RIGHT ( TT )
- READ ( TT, 900, ERR=1000 ) NUM
- FSTACK(ISP) = FSTACK(ISP)**NUM
- C
- C ----- MULTIPLY
- C
- ELSE IF (TOKE(I) .EQ. '*') THEN
- ISP = ISP - 1
- FSTACK(ISP) = FSTACK(ISP) * FSTACK(ISP+1)
- C
- C ----- DIVIDE
- C
- ELSE IF (TOKE(I) .EQ. '/') THEN
- ISP = ISP - 1
- FSTACK(ISP) = FSTACK(ISP) / FSTACK(ISP+1)
- C
- C ----- OTHERWISE THE TOKEN IS A UNIT
- C
- ELSE
- C
- C -------- IF THE TOKEN IS NUMERIC, DO NOTHING---
- C -------- IF IT IS ALPHA, ADD FACTOR TO STACK
- C
- IF ((TOKE(I)(1:1) .LT. '0') .OR.
- $ (TOKE(I)(1:1) .GT. '9')) THEN
- ISP = ISP + 1
- FSTACK(ISP) = FACTS(I)
- ENDIF
- ENDIF
- 100 CONTINUE
- FAC = FSTACK(ISP)
- C
- C --- PASS 2, DETERMINE WHICH SYMBOLS ARE IN NUMERATOR AND DENOMINATOR
- C
- NT = 0
- NB = 0
- ISP = 0
- DO 200 I = 1, NTOKE
- C
- C ----- FOR EXPONENTIATION, ADD THE STRING TO ITSELF 'NUM' TIMES.
- C
- IF ( TOKE(I) .EQ. '^') THEN
- TT = TSTACK(ISP)
- ISP = ISP - 1
- CALL RIGHT ( TT )
- READ ( TT, 900, ERR=1000 ) NUM
- T1 = TSTACK(ISP)
- B1 = BSTACK(ISP)
- ISP = ISP - 1
- T = ' '
- B = ' '
- IT = 1
- IB = 1
- LT = LENGTH(T1)
- LB = LENGTH(B1)
- IF (LT .GT. 0) THEN
- DO 10 II = 1, NUM
- T(IT:IT+LT-1) = T1(1:LT)
- IT = IT + LT
- T(IT:IT) = '*'
- IT = IT + 1
- 10 CONTINUE
- ENDIF
- IF (LB .GT. 0) THEN
- DO 15 II = 1, NUM
- B(IB:IB+LB-1) = B1(1:LB)
- IB = IB + LB
- B(IB:IB) = '*'
- IB = IB + 1
- 15 CONTINUE
- ENDIF
- IT = IT - 1
- IB = IB - 1
- T(IT:IT) = ' '
- B(IB:IB) = ' '
- ISP = ISP + 1
- TSTACK(ISP) = T
- BSTACK(ISP) = B
- C
- C ----- FOR A MULTIPLY, ADD STRINGS FROM THE SAME SIDE OF THE STACK.
- C
- ELSE IF (TOKE(I) .EQ. '*') THEN
- T = TSTACK(ISP)
- B = BSTACK(ISP)
- ISP = ISP - 1
- T1 = TSTACK(ISP)
- B1 = BSTACK(ISP)
- ISP = ISP - 1
- LT = LENGTH ( T )
- LB = LENGTH ( B )
- LT1 = LENGTH ( T1 )
- LB1 = LENGTH ( B1 )
- C
- C -------- CHECK TO SEE THAT THERE WAS AN ENTRY IN BOTH LOCATIONS
- C
- IF ((LT .GT. 0) .AND. (LT1 .GT. 0)) THEN
- LT = LT + 1
- T(LT:LT) = '*'
- ENDIF
- IF ((LB .GT. 0) .AND. (LB1 .GT. 0)) THEN
- LB = LB + 1
- B(LB:LB) = '*'
- ENDIF
- LT = LT + 1
- LB = LB + 1
- IF (LT1 .GT. 0) THEN
- T(LT:LT+LT1-1) = T1(1:LT1)
- ENDIF
- IF (LB1 .GT. 0) THEN
- B(LB:LB+LB1-1) = B1(1:LB1)
- ENDIF
- ISP = ISP + 1
- TSTACK(ISP) = T
- BSTACK(ISP) = B
- C
- C ----- FOR A DIVIDE, ADD STRINGS FROM OPPOSITE SIDES OF THE STACK.
- C
- ELSE IF (TOKE(I) .EQ. '/') THEN
- T = TSTACK(ISP)
- B = BSTACK(ISP)
- ISP = ISP - 1
- T1 = TSTACK(ISP)
- B1 = BSTACK(ISP)
- ISP = ISP - 1
- LT = LENGTH ( T )
- LB = LENGTH ( B )
- LT1 = LENGTH ( T1 )
- LB1 = LENGTH ( B1 )
- IF ((LT1 .GT. 0) .AND. (LB .GT. 0)) THEN
- LT1 = LT1 + 1
- T1(LT1:LT1) = '*'
- ENDIF
- IF ((LB1 .GT. 0) .AND. (LT .GT. 0)) THEN
- LB1 = LB1 + 1
- B1(LB1:LB1) = '*'
- ENDIF
- LT1 = LT1 + 1
- LB1 = LB1 + 1
- IF (LB .GT. 0 ) THEN
- T1(LT1:LT1+LB-1) = B(1:LB)
- ENDIF
- IF (LT .GT. 0 ) THEN
- B1(LB1:LB1+LT-1) = T(1:LT)
- ENDIF
- ISP = ISP + 1
- TSTACK(ISP) = T1
- BSTACK(ISP) = B1
- C
- C ----- OTHERWISE THE TOKEN IS A UNIT, PUT IT ON THE TOP SIDE OF STACK
- C
- ELSE
- ISP = ISP + 1
- TSTACK(ISP) = TOKE(I)
- BSTACK(ISP) = ' '
- ENDIF
- 200 CONTINUE
- C
- C --- NOW PARSE THE TOP STRINGS INTO ARRAYS OF UNITS
- C
- T = TSTACK(ISP)
- B = BSTACK(ISP)
- LT = LENGTH ( T )
- LB = LENGTH ( B )
- NT = 0
- NB = 0
- I = 1
- 205 NT = NT + 1
- INT = 1
- TOP(NT) = ' '
- 210 TOP(NT)(INT:INT) = T(I:I)
- INT = INT + 1
- I = I + 1
- IF (I .GT. LT) GO TO 250
- IF (T(I:I) .NE. '*') GO TO 210
- I = I + 1
- IF (I .LE. LT) GO TO 205
- C
- 250 I = 1
- 300 NB = NB + 1
- INT = 1
- BOT(NB) = ' '
- 310 BOT(NB)(INT:INT) = B(I:I)
- INT = INT + 1
- I = I + 1
- IF (I .GT. LB) GO TO 1000
- IF (B(I:I) .NE. '*') GO TO 310
- I = I + 1
- IF (I .LE. LB) GO TO 300
- 1000 RETURN
- 900 FORMAT ( I6 )
- END
- C
- C---END EVAL
- C
-